#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


#define SIZE 1024
#define MAX_ARGC 64
#define SEP " "

char* argv[MAX_ARGC];
char pwd[SIZE];
char env[SIZE];
int lastcode = 0;


const char* HostName()
{
  char* hostname = getenv("HOSTNAME");
  if(hostname)
    return hostname;
  else
    return "None";
}

const char* UserName()
{
  char* username = getenv("USER");
  if(username)
    return username;
  else
    return "None";
}

const char* CurrentWorkDir()
{
  char* route = getenv("PWD");
  if(route)
    return route;
  else
    return "None";
}


char* Home()
{
  return getenv("HOME");
}

int  BuildinCmd()
{
  int ret = 0;
  //检查是否是内建命令
  if(strcmp("cd",argv[0]) == 0)
  {
    ret =  1;
    char* target = argv[1];
    if(!target) target = Home();
    chdir(target);
    char temp[1024];
    getcwd(temp,1024);
    snprintf(pwd,SIZE,"PWD=%s",temp);
    putenv(pwd);
  }
  else if(strcmp("export",argv[0]) == 0)
  {
    ret =  1;
    char* target = argv[1];
    if(!target) target = Home();
    chdir(target);
    char temp[1024];
    getcwd(temp,1024);
    snprintf(pwd,SIZE,"PWD=%s",temp);
    putenv(pwd);
  }
  else if(strcmp("echo",argv[0]) == 0)
  {
    ret =  1;
    if(argv[1] == NULL)
    {
      printf("\n");
    }
    else{
      if(argv[1][0] == '$')
      {
        if(argv[1][1] == '?')
        {
          printf("%d\n",lastcode);
          lastcode = 0;
        }
        else
        {
          char* e = getenv(argv[1]+1);
          if(e) 
            printf("%s\n",e);
        }
      }
      else{
        printf("%s\n",argv[1]);
      }
    }
  }
  return ret;
}



int Interractive(char out[],int size)
{
  printf("[%s@%s %s]$",UserName(),HostName(),CurrentWorkDir());
  fgets(out,size,stdin);
  out[strlen(out) - 1] = 0;//用0把我们输入的换行替换

  return strlen(out); 
}

void Split(char in[])
{
  int i = 0;
  argv[i++] = strtok(in,SEP);
  while(argv[i++] = strtok(NULL,SEP));
  
}

void Execute()
{
  pid_t id = fork();
  if(id == 0)
  {
    execvp(argv[0],argv);
    exit(1);
  }
  int status = 0;
  pid_t rid = waitpid(id,&status,0);
  if(rid == id) lastcode = WEXITSTATUS(status);
}


int main()
{
  while(1)
  {
  char commandline[SIZE];
  //打印命令行提示符，获取用户输入的命令字符
  int n = Interractive(commandline,SIZE);
  
  if(n == 0) continue;

  //对命令行字符串进行切割
  Split(commandline);

  //处理内建命令
  n = BuildinCmd();

  //执行命令
  Execute();
  }
  return 0;
}
